---
title: "JWT Middleware with Authorization Headers"
description: "AgentOS with JWT middleware for authentication and parameter injection using Authorization headers"
---

This example demonstrates how to use JWT middleware with AgentOS for authentication and automatic parameter injection using Authorization headers.

## Code

```python jwt_middleware.py
from datetime import UTC, datetime, timedelta

import jwt
from agno.agent import Agent
from agno.db.postgres import PostgresDb
from agno.models.openai import OpenAIChat
from agno.os import AgentOS
from agno.os.middleware import JWTMiddleware

# JWT Secret (use environment variable in production)
JWT_SECRET = "a-string-secret-at-least-256-bits-long"

# Setup database
db = PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")


# Define a tool that uses dependencies claims
def get_user_details(dependencies: dict):
    """
    Get the current user's details.
    """
    return {
        "name": dependencies.get("name"),
        "email": dependencies.get("email"),
        "roles": dependencies.get("roles"),
    }


# Create agent
research_agent = Agent(
    id="user-agent",
    model=OpenAIChat(id="gpt-5-mini"),
    db=db,
    tools=[get_user_details],
    instructions="You are a user agent that can get user details if the user asks for them.",
)


agent_os = AgentOS(
    description="JWT Protected AgentOS",
    agents=[research_agent],
)

# Get the final app
app = agent_os.get_app()

# Add JWT middleware to the app
# This middleware will automatically inject JWT values into request.state and is used in the relevant endpoints.
app.add_middleware(
    JWTMiddleware,
    secret_key=JWT_SECRET, # or use JWT_SECRET_KEY environment variable
    algorithm="HS256",
    user_id_claim="sub",  # Extract user_id from 'sub' claim
    session_id_claim="session_id",  # Extract session_id from 'session_id' claim
    dependencies_claims=["name", "email", "roles"],
    # In this example, we want this middleware to demonstrate parameter injection, not token validation.
    # In production scenarios, you will probably also want token validation. Be careful setting this to False.
    validate=False,
)

if __name__ == "__main__":
    """
    Run your AgentOS with JWT parameter injection.
    
    Test by calling /agents/user-agent/runs with a message: "What do you know about me?"
    """
    # Test token with user_id and session_id:
    payload = {
        "sub": "user_123",  # This will be injected as user_id parameter
        "session_id": "demo_session_456",  # This will be injected as session_id parameter
        "exp": datetime.now(UTC) + timedelta(hours=24),
        "iat": datetime.now(UTC),
        # Dependency claims
        "name": "John Doe",
        "email": "john.doe@example.com",
        "roles": ["admin", "user"],
    }
    token = jwt.encode(payload, JWT_SECRET, algorithm="HS256")
    print("Test token:")
    print(token)
    agent_os.serve(app="jwt_middleware:app", port=7777, reload=True)
```

## Usage

<Steps>
  <Snippet file="create-venv-step.mdx" />

  <Step title="Set Environment Variables">
    ```bash
    export OPENAI_API_KEY=your_openai_api_key
    ```
  </Step>

  <Step title="Install libraries">
    ```bash
    pip install -U agno openai pyjwt "fastapi[standard]" uvicorn sqlalchemy pgvector psycopg
    ```
  </Step>

  <Step title="Setup PostgreSQL Database">
    ```bash
    # Using Docker
    docker run -d \
      --name agno-postgres \
      -e POSTGRES_DB=ai \
      -e POSTGRES_USER=ai \
      -e POSTGRES_PASSWORD=ai \
      -p 5532:5432 \
      pgvector/pgvector:pg17
    ```
  </Step>

  <Step title="Run Example">
    ```bash
    python jwt_middleware.py
    ```
    
    The server will start and print a test JWT token to the console.
  </Step>

  <Step title="Test JWT Authentication">
    
    **Test with the generated token:**
    ```bash
    # Use the token printed in the console
    export TOKEN="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
    
    curl --location 'http://localhost:7777/agents/user-agent/runs' \
        --header 'Content-Type: application/x-www-form-urlencoded' \
        --header 'Authorization: Bearer $TOKEN' \
        --data-urlencode 'message=What do you know about me?'
    ```
    
    **Test without token (should still work since validate=False):**
    ```bash
    curl --location 'http://localhost:7777/agents/user-agent/runs' \
        --header 'Content-Type: application/x-www-form-urlencoded' \
        --data-urlencode 'message=What do you know about me?'
    ```
    
    **Check the AgentOS API docs:**
    Visit http://localhost:7777/docs to see all available endpoints.
  </Step>
</Steps>

## How It Works

1. **JWT Generation**: The example creates a test JWT token with user claims
2. **Middleware Setup**: JWT middleware extracts claims from the `Authorization: Bearer <token>` header  
3. **Parameter Injection**: The middleware automatically injects:
   - `user_id` from the `sub` claim
   - `session_id` from the `session_id` claim
   - `dependencies` dict with name, email, and roles
4. **Agent Tools**: The agent can access user details through the injected dependencies


## Next Steps

- [JWT Middleware with Cookies](/examples/agent-os/middleware/jwt-cookies)
- [Custom FastAPI with JWT](/examples/agent-os/middleware/custom-fastapi-jwt)
- [JWT Middleware Documentation](/agent-os/customize/middleware/jwt)
